package com.lpf.aspect;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Enumeration;

@Slf4j
@Aspect
@Component
public class WebLogAspect {

    @Pointcut("execution(public * com.mchz.identity.controller..*.*(..))*")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {

        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();

        log.info("========================================== Start ==========================================");

        log.info("URL：" + request.getRequestURL().toString());
        log.info("HTTP_METHOD：" + request.getMethod());

        log.info("HTTP_HEADERS: ");
        Enumeration<?> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = (String) enumeration.nextElement();
            String value = request.getHeader(key);
            log.info("     {}: {}", key, value);
        }

        log.info("IP：" + request.getRemoteAddr());
        log.info("CLASS_METHOD：" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        try {
            Object[] args = joinPoint.getArgs();
            log.info("REQUEST BODY : [{}]", JSONUtil.toJsonStr(args));
        } catch (Exception e) {
            log.error("REQUEST BODY PARSE ERROR!");
        }

        HttpSession session = (HttpSession) servletRequestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
        log.info("SESSION ID：" + session.getId());
    }

    @After("webLog()")
    public void doAfter() {
        log.info("=========================================== End ===========================================");
        log.info("");
    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        String resultStr = JSONUtil.toJsonStr(result);
        if (resultStr.length() > 500) {
            log.info("RESPONSE DATA  : {}", "TOO MANY DATA");
        } else {
            log.info("RESPONSE DATA  : {}", resultStr);
        }
        log.info("TIME CONSUMING : {} ms", System.currentTimeMillis() - startTime);
        return result;
    }

}

